﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace RITInterativeMap
{
    class CustomSwipeDetector : Kinect.Toolbox.SwipeGestureDetector
    {

        protected override void LookForGesture()
        {
            base.LookForGesture();
            const float SwipeMinimalLength = 0.2f;
            const float SwipeMaximalHeight = 0.4f;
            const int SwipeMinimalDuration = 250;
            const int SwipeMaximalDuration = 1500;

            // Swipe Up
            if (ScanPositions((p1, p2) => Math.Abs(p2.Y - p1.Y) > SwipeMaximalHeight, // Height
                (p1, p2) => p2.Y - p1.Y > -0.01f, // Progression upwards
                (p1, p2) => Math.Abs(p2.X - p1.X) < SwipeMinimalLength, // Length
                SwipeMinimalDuration, SwipeMaximalDuration)) // Duration
            {
                RaiseGestureDetected("SwipeUp");
                return;
            }

            // Swipe Down
            if (ScanPositions((p1, p2) => Math.Abs(p2.Y - p1.Y) > SwipeMaximalHeight,  // Height
                (p1, p2) => p2.Y - p1.Y < 0.01f, // Progression downwards
                (p1, p2) => Math.Abs(p2.X - p1.X) < SwipeMinimalLength, // Length
                SwipeMinimalDuration, SwipeMaximalDuration))// Duration
            {
                RaiseGestureDetected("SwipeDown");
                return;
            }
        }

        bool ScanPositions(Func<Kinect.Toolbox.Vector3, Kinect.Toolbox.Vector3, bool> heightFunction, Func<Kinect.Toolbox.Vector3, Kinect.Toolbox.Vector3, bool> directionFunction, Func<Kinect.Toolbox.Vector3, Kinect.Toolbox.Vector3, bool> lengthFunction, int minTime, int maxTime)
        {
            int start = 0;

            for (int index = 1; index < Entries.Count - 1; index++)
            {
                if (!heightFunction(Entries[0].Position, Entries[index].Position) || !directionFunction(Entries[index].Position, Entries[index + 1].Position))
                {
                    start = index;
                }

                if (lengthFunction(Entries[index].Position, Entries[start].Position))
                {
                    double totalMilliseconds = (Entries[index].Time - Entries[start].Time).TotalMilliseconds;
                    if (totalMilliseconds >= minTime && totalMilliseconds <= maxTime)
                    {
                        return true;
                    }
                }
            }

            return false;
        }
    }
}
